/**
 * app/util/common.js                   通用js
 *
 * @author                              mashanling(msl-138@163.com)
 * @date                                2012-03-31 21:50:47
 * @last modify                         2012-07-04 10:05:55 by mashanling
 */

var DOMAIN = {//域名
    imgcache: 'http://v2.imgcache.extjs.mrmsl.com/',
    data: 'http://v2.extjs.mrmsl.com/'
};

var C = {//常用配置
    dataType: 'ajax',//'jsonp'
    headerSortCls: {//grid头部排序class类名
        ASC: 'x-column-header-sort-ASC',
        DESC: 'x-column-header-sort-DESC',
    },
    dateFormat: 'Y-m-d H:i:s',
    dayFormat: 'Y-m-d',
    timeFormat: 'H:i:s',
    path: { //路径信息
        js: '',
        app: 'app/',
        data: 'app/data/',
        store: 'app/store/',
        model: 'app/model/',
        controller: 'app/controller/',
        view: 'app/view/'
    },
    images: {
        yes: DOMAIN.imgcache + 'images/icons/yes.gif',
        no: DOMAIN.imgcache + 'images/icons/no.gif'
    }
};

C.images['0'] = '<img alt="" src="' + C.images.no + '" />';
C.images['1'] = '<img alt="" src="' + C.images.yes + '" />';

var TEXT = {//提示文字信息
    common: function(color, text, extra) {
        return '<span style="color: {0};{1}">{2}</span>'.format(color, extra || '', text);
    },
    red: function(text) {//红
        return this.common('red', text || '*');
    },
    green: function(text) {//绿
        return this.common('red', text);
    },
    gray: function(text, extra) {//灰
        return this.common('gray', text, extra === undefined ? 'padding-left: 4px;' : '');
    }
};

String.prototype.format = function() {//字符串格式化输出

    if (typeof arguments[0] == 'object') {//json形，如'a{a}b{b}'.format({a: 'a', b: 'b'}) => aabb
        var args = arguments[0], pattern = /\{(\w+)\}/g;
    }
    else {//数字形，如format('a{1}b{2}', 'a', 'b') => aabb
        var args = arguments, pattern = /\{(\d+)\}/g;
    }

    return this.replace(pattern, function(m, i) {
        return args[i];
    });
};

String.prototype.ltrim = function() {
    return this.replace(/^\s+/, '');
};
String.prototype.rtrim = function() {
    return this.replace(/\s+$/, '');
};
String.prototype.trim = function() {
    return this.ltrim().rtrim();
};

/**
 * 设置或获取语言，支持批量
 * 
 * @author      mashanling(msl-138@163.com)
 * @date        2012-07-04 11:17:12
 * @last modify 2012-07-04 11:17:12 by mashanling 
 * 
 * @param {mixed} name  名
 * @param {mixed} value 值
 * 
 * @return mixed 如果不传参数name，将返回整个语言包；如果name为object或传value，将设置语言；否则返回指定语言
 */
function lang(name, value) {

    if (!name) {//返回整个语言包
        return L;
    }
    else if (typeof(name) == 'object') {//批量设置
        return Ext.apply(L, name);
    }
    else if (value !== undefined) {//单个
        L[name.toUpperCase()] = value;
        return L;
    }
    else {//取值
        var _lang = '';
        
        Ext.each(name.split(','), function(item) {
            
            if (item.indexOf('%') == 0) {//支持原形返回
                _lang += item.substr(1);
            }
            else {//如果设置值，返回值，否则只返回键名
            item = item.toUpperCase();
                _lang += L[item] === undefined ? item : L[item]
            }
            
        });
        
        return _lang;
    }
}

/**
 * console.log
 *
 * @return {void} 无返回值
 */
function log() {
    var len = arguments.length;

    if (typeof(console) != 'undefined') {
        var i = 0;

        for (i = 0; i < len; i++) {
            console.log(arguments[i]);
        }
    }
}

/**
 * 去掉html标签
 *
 * @param {string} str 字符串
 * @param {bool}   img 是否保留img标签，默认false，不保留
 *
 * @return {string} 去掉html标签后的字符串
 */
function strip_tags(str, img) {
    str = String(str);
    var pattern = img ? /<(?!img)[^>]*>/ig : /<[^>]*>/gi;

    return str.replace(pattern, '');
}

/**
 * 转化为整数
 *
 * @param {mixed} str   需要转换的字符串
 * @param {int}   def   转换失败默认值，默认0
 * @param {int}   radix 进制，默认十进制
 *
 * @return {int} 转化后的整数
 */
function intval(str, def, radix) {
    radix = radix || 10;
    var str = parseInt(str, radix);

    return isNaN(str) ? parseInt(def == undefined ? 0 : def, radix) : str;
}

/**
 * 转化为浮点数
 *
 * @param {mixed} str   需要转换的字符串
 * @param {float} def   转换失败默认值，默认0.00
 *
 * @return {float} 转化后的浮点数
 */
function toFloat(str, def) {
    var str = parseFloat(str);

    return isNaN(str) ? parseFloat(def == undefined ? 0.00 : def) : str;
}

/**
 * 数字精确度
 *
 * @param {int} value     数字
 * @param {int} precision 小数点位数，默认2
 *
 * @return {float} 精确小数点后的数值
 */
function toFixed(value, precision) {
    precision = precision === undefined ? 2 : precision;

    if ((0.9).toFixed() !== '1') {//IE下等于0
        var pow = Math.pow(10, precision);
        return (Math.round(value * pow) / pow).toFixed(precision);
    }

    return value.toFixed(precision);
}

/**
 * 使用另一个字符串填充字符串为指定长度
 *
 * @param string string     待填充字符串
 * @param int    lendgh     总长度，默认10
 * @param string pad        填充字符，默认' '
 * @param string padType    填充类型，默认左填充
 *
 * @return {string} 填充后的字符串
 */
function str_pad(str, length, pad, padType) {
    str = String(str);
    length = length ? length : 10;
    pad = pad == undefined ? ' ' : pad;

    while (str.length < length) {
        str = padType == 'right' ? str + pad : pad + str;
    }

    return str;

}

/**
 * html转码
 *
 * @param {string} str 待转换字符串
 *
 * @param {string} 转换后的字符串
 */
function htmlspecialchars(str) {
    return str.replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;').replace(/\'/g, '&#39;');
}

/**
 * 反转html
 *
 * @param {string} str 待转换字符串
 *
 * @param {string} 转换后的字符串
 */
function unhtmlspecialchars(str) {
    return str.replace(/\&lt;/g, '<').replace(/\&gt;/g, '>').replace(/\&quot;/g, '"').replace(/\&#39;/g, "'");
}

/**
 * 输入框获、失焦点处理
 *
 * @param {object} obj  html元素
 * @param {string} def  默认内容，默认为元素初始值
 *
 * @return {object} html元素
 */
function setFocus(obj, def) {
    def = def || obj.defaultValue;
    obj.value.trim() == def ? obj.value = '' : '';

    obj.onblur = function() {
        obj.value.trim() == '' ? obj.value = def : '';
    };

    return obj;
}

/**
 * 格式化时间
 *
 * @param {string} format      格式
 * @param {mixed}  constructor 日期初始化参数
 *
 * @return {string} 格式化后的时间
 */
function date(format, constructor) {

    if (typeof(constructor) == 'object') {//已经是日期类型
        var datetime = constructor;
    }
    else {
        var datetime = constructor ? new Date(constructor) : new Date();
    }

    format = format || 'Y-m-d H:i:s';

    var o = {
        'Y': datetime.getFullYear(),
        'm': datetime.getMonth() + 1,
        'd': datetime.getDate(),
        'H': datetime.getHours(),
        'i': datetime.getMinutes(),
        's': datetime.getSeconds()
    };

    for (var i in o) {
        _s = i == 'Y' ? o[i] : str_pad(o[i], 2, '0');//不为年，补0
        format = format.replace(new RegExp(i, 'g'), _s);
    }

    return format;
}

/**
 * 获取参数
 *
 * @param {string} name 参数
 * @param {string} str  待获取字符串，默认location.href
 *
 * @return {string} 参数值
 */
function _GET(name, str) {
    var pattern = new RegExp('[\?&]' + name + '=([^&]+)', 'g');
    str = str || location.href;
    var arr, match = '';

    while ((arr = pattern.exec(str)) !== null) {
        match = arr[1];
    }

    return match;
}

/**
 *
 * @param {string} sort  排序字段
 * @param {string} order 排序
 *
 * @return {void} 无返回值
 */
function setSort(sort, order) {
    var classes = [C.headerSortCls.ASC, C.headerSortCls.DESC];
    order = C.headerSortCls[order];

    if (order) {//存在排序
        Ext.each(this.columns, function(item) {
            item.removeCls(classes);
            item.dataIndex == sort && item.addCls(order);
        });
    }
}

/**
 * 消息弹出层标题
 *
 * @param {string} title
 *
 * @return {string} 标题
 */
function getMsgTitle(title) {
    return title || lang('SYSTEM_INFOMATION');
}

/**
 * 提示
 *
 * @param {string} msg    内容
 * @param {string} title  标题
 * @param {bool}   green  绿色字体，默认
 *
 * @return {void} 无返回值
 */
function info(msg, title, green) {
    msg = green === undefined ? TEXT.green(msg) : msg;
    Ext.Msg.show({
        msg: msg,
        title: getMsgTitle(title),
        icon: Ext.Msg.INFO,
        buttons: Ext.Msg.OK,
        modal: true
    });
}

/**
 * 警告
 *
 * @param {string} msg    内容
 * @param {string} title  标题
 *
 * @return {void} 无返回值
 */
function warn(msg, title) {
    Ext.Msg.show({
        msg: msg,
        title: getMsgTitle(title),
        icon: Ext.Msg.WARNING,
        buttons: Ext.Msg.OK,
        modal: true
    });
}

/**
 * 错误
 *
 * @param {string} msg    内容
 * @param {string} title  标题
 * @param {bool}   red    红色字体，默认
 *
 * @return {void} 无返回值
 */
function error(msg, title, red) {
    msg = red === undefined ? TEXT.red(msg) : msg;
    Ext.Msg.show({
        msg: msg,
        title: getMsgTitle(title),
        icon: Ext.Msg.ERROR,
        buttons: Ext.Msg.OK,
        modal: true
    });
}

/**
 * 友好提示
 *
 * @param {string} msg      提示内容
 * @param {bool}   success  是否成功提示，默认是
 * @param {bool}   cancel   是否清除提示，默认不是
 * @param {int}    timeout  提示停留时间，单位毫秒，默认1500
 *
 * @param {void} 无返回值
 */
function Alert(msg, success, cancel, timeout) {
    var div = Ext.get('div-alert'), body = Ext.getBody();

    if (!cancel) {

        if (success === 'loading') {
            var background = '#ff8', color = '#333';
        }
        else {
            var color = '#fff', background = success === undefined ? '#16960e' : '#d90000';
        }

        if (!div) {
            div = Ext.DomHelper.append(body, {
                id: 'div-alert',
                style: 'float: left; position: absolute; padding: 4px 10px'
            }, true).hover(function() {
                Ext.get(this).show(true);
                clearInterval(window.AlertTimeout);
            }, hideAlert);
        }
        else {
            div.hide();
            clearInterval(window.AlertTimeout);
        }

        div.update(msg);
        div.show().setStyle({
            color: color,
            width: 'auto',
            'background-color': background,
            nothing: true
        });
        var width = div.getWidth();
        width = Ext.Number.constrain(width, 100, 800);
        div.setStyle({
            width: width + 'px',
            'text-align': width < 800 ? 'center' : 'left'
        }).alignTo(body, 't', [-width / 2, 0]);
        hideAlert(timeout);
    }

    else {
        div.hide();
    }
}//end Alert

/**
 * 隐藏友好提示
 *
 * @param {int}    timeout  提示停留时间，单位毫秒，默认2000
 *
 * @param {void} 无返回值
 */
function hideAlert(timeout) {

    if (timeout !== false) {
        window.AlertTimeout = setTimeout(function() {
            Alert(false, false, true);
        }, timeout || 2000);
    }
}


/**
 * 判断是否有选择
 *
 * @param {object} selModel   selModel
 * @param {mixed}  internalId internalId
 * @param {string} separator  分割符，默认半角逗号
 *
 * @return mixed 如果有选择,返回用separator分割的字符串，否则返回false，并提示
 */
function hasSelect(selModel, internalId, separator) {
    var selection = selModel.getSelection ? selModel.getSelection() : selModel.getChecked();
    separator = separator || ',';

    if (selection.length == 0) {
        !arguments[3] && Alert(lang('SELECT_ONE'), false);
        return false;
    }

    if (internalId === undefined) {//返回内部主键
        return Ext.Array.pluck(selection, 'internalId').join(separator);
    }
    else if (Ext.isFunction(internalId)) {
        return internalId.call(selection);
    }

    var ids = [];

    if (Ext.isString(internalId) && internalId.indexOf(',') > -1) {
        var arr = internalId.split(',');

        Ext.each(selection, function(item) {
            var v = [];

            Ext.each(arr, function(a) {
                v.push(item.get(a));
            });

            ids.push(v.join('|'));
        });
    }
    else {
        Ext.each(selection, function(item) {
            ids.push(item.get(internalId));
        });
    }

    return ids.join(separator);
}

/**
 * 获取请求url
 *
 * @param {string} action 请求action
 *
 * @return string 请求url
 */
function getActionUrl(action) {
    return '/admin.php/' + action;
}

/**
 * 获取controller=controller&action=action
 *
 * @param {string} controller 控制器
 * @param {string} action     操作
 *
 * @return {string}
 */
function getAction(controller, action) {
    return 'controller={0}&action={1}'.format(controller, action);
}

/**
 * 通用ajax操作
 *
 * @param {object} options 参数
 *
 * @return {void} 无返回值
 */
function commonAction(options) {
    var args = arguments;//, scope = scope || window;

    setLoading();

    Ext.Ajax.request({
        url: getActionUrl(options.action),
        params: Ext.isString(options.data) ? Ext.Object.fromQueryString(options.data) : options.data,
        callback: function(opt, success, response) {
            setLoading(false);
            var data = Ext.decode(response.responseText);

            if (data && data.success) {

                if (Ext.isFunction(options.callback)) {
                    options.callback.apply(options.scope || window, options.callbackArgs);
                }

                options.pagingbar && options.pagingbar.doRefresh();
                options.store && options.store.load();
                Alert(data.msg);
            }
            else {
                error(data && data.msg ? data.msg : options.failedMsg || lang('OPERATE,FALIURE'));
            }
        }
    });
}

/**
 * 确认操作
 *
 * @param {object} options 参数
 *
 * @return {void} 无返回值
 */
function myConfirm(options) {
    Ext.Msg.confirm(getMsgTitle(), options.confirmText, function(btn) {
        btn == 'yes' && commonAction(options);
    });
}

/**
 * 获取控制器
 *
 * @param {string} controller 控制器名
 *
 * @return {mixed} 如果控制器存在，返回控制器实例，如果不存在，抛出异常
 */
function getController(controller) {
    try {
        return App.App.getController('App.controller.' + controller);
    }
    catch (e) {
        Ext.Error.raise(e);
    }
}

/**
 * 设置或取消遮罩
 *
 * @param {mixed} msg 遮罩信息，如果为false，则为取消遮罩
 *
 * @return {void} 无返回值
 */
function setLoading(msg) {
    msg === false ? Alert(false, false, true, false) : Alert(msg || lang('PROCESSING'), 'loading', false, false);
    //bodyMask(msg);
}

/**
 * 设置或取消遮罩
 *
 * @param {mixed} msg 遮罩信息，如果为false，则为取消遮罩
 *
 * @return {void} 无返回值
 */
function bodyMask(msg) {
    var body = Ext.getBody();

    msg === false ? body.unmask() : body.mask(msg || lang('PROCESSING'));
}

/**
 * 设置导航
 *
 * @param {object} data 标签数据
 *
 * @return {void} 无返回值
 */
function setHistory(data) {
    var tab = App.cmp.tabs.getActiveTab();
    Ext.apply(tab, data);
    var href = Ext.Object.toQueryString(tab);
    App.History.push(href, true);
    Ext.get(tab.controller).dom.href = href;
}

/**
 * 加载数据异常配置
 *
 * @return {object} 异常配置
 */
function exception() {
    return {
        /**
         * 加载数据异常处理
         *
         * @param {object} proxy     Ext.data.proxy.Proxy
         * @param {object} response  The response from the AJAX request
         * @param {object} operation The operation that triggered request
         * @param {object} eOpts     The options object passed to Ext.util.Observable.addListener.
         *
         * @return {void} 无返回值
         */
        exception: function(proxy, response, operation, eOpts) {
            log(response.statusText);
            error(lang('SERVER_ERROR'));
        }
    }
}